package com.arvin.faceDetect.utils

import android.graphics.Bitmap
import android.graphics.Rect
import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicYuvToRGB
import com.google.mlkit.vision.face.Face
import kotlin.math.abs
import android.util.Log

/**
 * 人脸质量检查器
 * 用于评估人脸图像的质量，包括：
 * 1. 清晰度检查
 * 2. 光照均匀性检查
 * 3. 姿态角度检查
 * 4. 遮挡检查
 */
class FaceQualityChecker {
    companion object {
        // 质量检查阈值
        private const val MIN_SHARPNESS = 0.3f
        private const val MIN_BRIGHTNESS = 60
        private const val MAX_BRIGHTNESS = 230
        private const val MAX_BRIGHTNESS_DEVIATION = 120.0
        private const val BRIGHTNESS_DEVIATION_RATIO = 1.5
        private const val MAX_POSE_ANGLE = 20f
        private const val MIN_FACE_CONFIDENCE = 0.8f
        private const val SAMPLE_STEP = 2
        private const val MIN_EYE_OPEN_PROBABILITY = 0.3f  // 降低眼睛睁开概率要求

        /**
         * 检查人脸质量
         * @param face ML Kit检测到的人脸
         * @param bitmap 原始图像
         * @return 质量检查结果
         */
        fun check(face: Face, bitmap: Bitmap): QualityCheckResult {
            // 使用 tracking 和面部特征概率来评估检测质量
            if (!face.trackingId.isValidTrackingId() ||
                face.leftEyeOpenProbability == null ||
                face.rightEyeOpenProbability == null
            ) {
                return QualityCheckResult(false, "人脸检测质量不足")
            }

            // 检查人脸姿态
            if (!isPoseAcceptable(face)) {
                return QualityCheckResult(false, "人脸姿态不合适")
            }

            // 检查人脸区域的图像质量
            val faceRegion = getFaceRegion(face.boundingBox, bitmap)
            if (!isSharpnessAcceptable(faceRegion)) {
                return QualityCheckResult(false, "人脸图像不够清晰")
            }

            // 检查光照条件
            val lightingResult = checkLighting(faceRegion)
            if (!lightingResult.first) {
                return QualityCheckResult(false, lightingResult.second)
            }

            // 检查是否有遮挡
            if (hasOcclusion(face)) {
                return QualityCheckResult(false, "人脸存在遮挡")
            }

            return QualityCheckResult(true, "人脸质量合格")
        }

        /**
         * 检查人脸姿态是否合适
         * @param face ML Kit检测到的人脸
         * @return Boolean 姿态是否合适
         */
        fun isPoseAcceptable(face: Face): Boolean {
            return abs(face.headEulerAngleY) <= MAX_POSE_ANGLE && // 左右转动
                    abs(face.headEulerAngleZ) <= MAX_POSE_ANGLE && // 歪头
                    abs(face.headEulerAngleX) <= MAX_POSE_ANGLE    // 上下点头
        }

        /**
         * 检查图像清晰度
         */
        private fun isSharpnessAcceptable(faceBitmap: Bitmap): Boolean {
            // 对图像进行降采样处理，提高性能
            val width = faceBitmap.width
            val height = faceBitmap.height
            val pixels = IntArray(width * height)
            faceBitmap.getPixels(pixels, 0, width, 0, 0, width, height)

            var sobelSum = 0.0
            var count = 0

            // 使用灰度值进行计算，并采用跳跃采样来提高性能
            for (y in SAMPLE_STEP until height - SAMPLE_STEP step SAMPLE_STEP) {
                for (x in SAMPLE_STEP until width - SAMPLE_STEP step SAMPLE_STEP) {
                    val p1 = getGrayScale(pixels[(y - SAMPLE_STEP) * width + (x - SAMPLE_STEP)])
                    val p2 = getGrayScale(pixels[(y - SAMPLE_STEP) * width + x])
                    val p3 = getGrayScale(pixels[(y - SAMPLE_STEP) * width + (x + SAMPLE_STEP)])
                    val p4 = getGrayScale(pixels[y * width + (x - SAMPLE_STEP)])
                    val p6 = getGrayScale(pixels[y * width + (x + SAMPLE_STEP)])
                    val p7 = getGrayScale(pixels[(y + SAMPLE_STEP) * width + (x - SAMPLE_STEP)])
                    val p8 = getGrayScale(pixels[(y + SAMPLE_STEP) * width + x])
                    val p9 = getGrayScale(pixels[(y + SAMPLE_STEP) * width + (x + SAMPLE_STEP)])

                    // 简化的Sobel算子计算
                    val gx = (p3 + 2 * p6 + p9) - (p1 + 2 * p4 + p7)
                    val gy = (p7 + 2 * p8 + p9) - (p1 + 2 * p2 + p3)

                    sobelSum += Math.sqrt((gx * gx + gy * gy).toDouble())
                    count++
                }
            }

            // 计算平均清晰度
            val sharpness = if (count > 0) sobelSum / count else 0.0

            // 添加日志输出便于调试
            Log.d("FaceQualityChecker", "Sharpness value: $sharpness")

            return sharpness >= MIN_SHARPNESS
        }

        /**
         * 将RGB像素值转换为灰度值
         */
        private fun getGrayScale(pixel: Int): Int {
            val r = (pixel shr 16) and 0xff
            val g = (pixel shr 8) and 0xff
            val b = pixel and 0xff
            // 使用加权平均法计算灰度值
            return (r * 0.299 + g * 0.587 + b * 0.114).toInt()
        }

        /**
         * 检查光照条件
         */
        private fun checkLighting(faceBitmap: Bitmap): Pair<Boolean, String> {
            // 直接返回通过
            return Pair(true, "光照检查已禁用")
        }

        /**
         * 检查是否有遮挡
         */
        private fun hasOcclusion(face: Face): Boolean {
            // 添加日志输出便于调试
            Log.d("FaceQualityChecker", "Occlusion check disabled")

            // 直接返回 false，表示没有遮挡
            return false
        }

        /**
         * 获取人脸区域的Bitmap
         */
        private fun getFaceRegion(boundingBox: Rect, originalBitmap: Bitmap): Bitmap {
            val left = maxOf(0, boundingBox.left)
            val top = maxOf(0, boundingBox.top)
            val width = minOf(boundingBox.width(), originalBitmap.width - left)
            val height = minOf(boundingBox.height(), originalBitmap.height - top)

            return Bitmap.createBitmap(
                originalBitmap,
                left,
                top,
                width,
                height
            )
        }

        // 扩展函数：检查 trackingId 是否有效
        private fun Int?.isValidTrackingId(): Boolean {
            return this != null && this >= 0
        }
    }

    /**
     * 质量检查结果
     * @param isAcceptable 是否通过质量检查
     * @param failureReason 失败原因（如果未通过检查）
     */
    data class QualityCheckResult(
        private val isAcceptable: Boolean,
        private val failureReason: String
    ) {
        fun isQualityAcceptable() = isAcceptable
        fun getFailureReason() = failureReason
    }
} 